import * as THREE from 'three';

import { Font, FontLoader } from 'three/examples/jsm/loaders/FontLoader';
import { TextGeometry } from 'three/examples/jsm/geometries/TextGeometry';
// import { GUI } from 'three/examples/jsm/libs/lil-gui.module.min.js'
THREE.Cache.enabled = true;

export default class TextFont {
  dom:HTMLElement | null = null
  scene: THREE.Scene | null = null;
  camera: THREE.PerspectiveCamera | null = null;
  renderer: THREE.WebGLRenderer | null = null;
  cameraTarget: THREE.Vector3 | null = null;
  group: THREE.Group | null = null;
  textMesh1: THREE.Mesh | null = null;
  textMesh2: THREE.Mesh | null = null;
  textGeo: TextGeometry | null = null;
  materials: Array<THREE.MeshPhongMaterial> = [];
  font:Font | null = null;
  mirror:boolean = true;
  text: string = '';
  domStyle:CSSStyleDeclaration | null = null

  pointerXOnPointerDown: number = 0;
  targetRotationOnPointerDown: number = 0;
  targetRotation: number = 0;
  pointerX: number = 0;
  onPointerMoveFun: (this: Document, ev: PointerEvent) => any = () => { };
  onPointerUpFun: (this: Document, ev: PointerEvent) => any = () => { };
  pause: boolean = false;

  constructor(dom: HTMLElement | null,text:string) {
    this.text = text
    if (dom) {
      this.dom = dom
      this.domStyle = window.getComputedStyle(this.dom)
      this.dom.style.touchAction = 'none'
    }
    this.init()
    this.animate()
  }
  init() {
    this.setScene()
    this.setCamera()
    this.setRenderer()
    this.setLight()
    this.setCube()
    this.loadFont();
    this.onPointerMoveFun=this.onPointerMove.bind(this)
    this.onPointerUpFun=this.onPointerUp.bind(this)
    // this.dom?.addEventListener('pointerdown', this.onPointerDown.bind(this));//是否支持拖拽旋转
    
  	// document.addEventListener( 'keypress', this.onDocumentKeyPress );
  	// document.addEventListener( 'keydown', this.onDocumentKeyDown );
  }
  // 设置场景
  setScene() {
    this.scene = new THREE.Scene();
    this.scene.background = new THREE.Color( 0x000000 );
    this.scene.fog = new THREE.Fog( 0x000000, 250, 1400 );
  }
  // 新建透视相机
  setCamera(): void {
    this.camera = new THREE.PerspectiveCamera( 30, parseInt(this.domStyle!.width) / parseInt(this.domStyle!.height), 1, 1500 );
    this.camera.position.set(0, 400, 700);
    this.cameraTarget = new THREE.Vector3( 0, 150, 0 );
    
  }
   // 设置渲染器
  setRenderer(): void {
    this.renderer = new THREE.WebGLRenderer();//==========================渲染器
    this.renderer.setPixelRatio( window.devicePixelRatio );
    // 设置画布的大小
    this.renderer.setSize(parseInt(this.domStyle!.width), parseInt(this.domStyle!.height));
    //这里 其实就是canvas 画布  renderer.domElement
    this.dom?.appendChild(this.renderer.domElement);
  }
  // 设置环境光
  setLight():void {
    const dirLight = new THREE.DirectionalLight( 0xffffff, 0.125 );
    dirLight.position.set( 0, 0, 1 ).normalize();
    this.scene?.add( dirLight );

    const pointLight = new THREE.PointLight( 0xffffff, 1.5 );
    pointLight.color.setHSL( Math.random(), 1, 0.5 );
    pointLight.position.set( 0, 100, 90 );
    this.scene?.add( pointLight );
  }
  // 加载字体模型
  loadFont(): void {
    const fontName = 'STXingkai'; // helvetiker, optimer, gentilis, droid sans, droid serif ,Microsoft YaHei 微软雅黑
		const	fontWeight = 'Regular'; // normal bold
    const loader = new FontLoader();
    loader.load( '/src/assets/fonts/' + fontName + '_' + fontWeight + '.typeface.json', ( font )=>{
      // refreshText();
      this.font = font
      this.createText()
    } );
  }
  // 创建网格模型(物体)
  setCube(): void {
    if (this.scene) {
      this.materials = [
        new THREE.MeshPhongMaterial( { color: 0xffffff, flatShading: true } ), // front
        new THREE.MeshPhongMaterial( { color: 0xffffff } ) // side
      ];

      this.group = new THREE.Group();
      this.group.position.y = 100;
      this.scene.add( this.group );

      const plane = new THREE.Mesh(
        new THREE.PlaneGeometry( 10000, 10000 ),
        new THREE.MeshBasicMaterial( { color: 0xffffff, opacity: 0.5, transparent: true } )
      );
      plane.position.y = 100;
      plane.rotation.x = - Math.PI / 2;
      this.scene.add( plane );
      this.render();
    }
  }
  createText() {
      let firstLetter = true;
			let	bevelEnabled = true
			const height = 20,
				size = 70,
				hover = 30,
				curveSegments = 4,
				bevelThickness = 2,
				bevelSize = 1.5;

    this.textGeo = new TextGeometry( this.text, {
      font: this.font as Font,
      size: size,
      height: height,
      curveSegments: curveSegments,
      bevelThickness: bevelThickness,
      bevelSize: bevelSize,
      bevelEnabled: bevelEnabled
    } );

    this.textGeo.computeBoundingBox();

    const centerOffset = - 0.5 * ( this.textGeo!.boundingBox!.max.x - this.textGeo!.boundingBox!.min.x );

    this.textMesh1 = new THREE.Mesh( this.textGeo, this.materials );

    this.textMesh1.position.x = centerOffset;
    this.textMesh1.position.y = hover;
    this.textMesh1.position.z = 0;

    this.textMesh1.rotation.x = 0;
    this.textMesh1.rotation.y = Math.PI * 2;

    this.group?.add( this.textMesh1 );

    if ( this.mirror ) {

      this.textMesh2 = new THREE.Mesh( this.textGeo, this.materials );

      this.textMesh2.position.x = centerOffset;
      this.textMesh2.position.y = - hover;
      this.textMesh2.position.z = height;

      this.textMesh2.rotation.x = Math.PI;
      this.textMesh2.rotation.y = Math.PI * 2;

      this.group?.add( this.textMesh2 );

    }

  }
  refreshText(text:string) {
    if(this.textMesh1&&this.textMesh2){
      this.group?.remove( this.textMesh1 );
      if ( this.mirror ) this.group?.remove( this.textMesh2 );
    }
    if ( ! text ) return;
    this.text = text
    this.createText();
  }
  // 渲染
  render() {
    if (this.group) {
      if (this.pause) {
        this.group.rotation.y += ( this.targetRotation - this.group.rotation.y ) * 0.05;//使用拖住旋转时注释
      }
    }
    this.camera?.lookAt( this.cameraTarget as THREE.Vector3 );
    this.renderer?.clear();
    this.renderer?.render( this.scene as THREE.Scene, this.camera as THREE.PerspectiveCamera );
  }
  // 动画调用
  animate():void {
    requestAnimationFrame(this.animate.bind(this));
    if (!this.pause) {
      this.group?.rotateY(0.01)
    }
    // this.group?.rotateX(0.01)
    this.render();
  }
  // 刷新页面
  resetRenderer() {
    if (this.camera && this.renderer) {
      this.camera.aspect =  parseInt(this.domStyle!.width) / parseInt(this.domStyle!.height);
      this.camera.updateProjectionMatrix();
      this.renderer.setSize( parseInt(this.domStyle!.width), parseInt(this.domStyle!.height));
    }
  }
  // pointerdown事件
  onPointerDown(event: PointerEvent) {
    if ( event.isPrimary === false ) return;
    this.pause = true
    this.pointerXOnPointerDown = event.clientX -  parseInt(this.domStyle!.width) / 2;
    this.targetRotationOnPointerDown = this.targetRotation;
    
    document.addEventListener( 'pointermove', this.onPointerMoveFun );
    document.addEventListener( 'pointerup', this.onPointerUpFun );
  }
  onPointerMove( event:PointerEvent ) {
    if ( event.isPrimary === false ) return;
    this.pointerX = event.clientX -  parseInt(this.domStyle!.width) / 2;
    this.targetRotation = this.targetRotationOnPointerDown + ( this.pointerX - this.pointerXOnPointerDown ) * 0.02;
  }
  onPointerUp(event:PointerEvent) {
    this.pause = false
    if ( event.isPrimary === false ) return;
    document.removeEventListener( 'pointermove', this.onPointerMoveFun );
    document.removeEventListener( 'pointerup', this.onPointerUpFun );
  }
}
			
			// function init() {

				// EVENTS

				

				//

				// const params = {
				// 	changeColor: function () {

				// 		pointLight.color.setHSL( Math.random(), 1, 0.5 );

				// 	},
				// 	changeFont: function () {

				// 		fontIndex ++;

				// 		fontName = reverseFontMap[ fontIndex % reverseFontMap.length ];

				// 		loadFont();

				// 	},
				// 	changeWeight: function () {

				// 		if ( fontWeight === 'bold' ) {

				// 			fontWeight = 'regular';

				// 		} else {

				// 			fontWeight = 'bold';

				// 		}

				// 		loadFont();

				// 	},
				// 	changeBevel: function () {

				// 		bevelEnabled = ! bevelEnabled;

				// 		refreshText();

				// 	}
				// };

				// //

				// const gui = new GUI();

				// gui.add( params, 'changeColor' ).name( 'change color' );
				// gui.add( params, 'changeFont' ).name( 'change font' );
				// gui.add( params, 'changeWeight' ).name( 'change weight' );
				// gui.add( params, 'changeBevel' ).name( 'change bevel' );
				// gui.open();

				//

				// window.addEventListener( 'resize', onWindowResize );

			// }


			//

			// function onDocumentKeyDown( event:Event ) {

			// 	if ( firstLetter ) {

			// 		firstLetter = false;
			// 		text = '';

			// 	}

			// 	const keyCode = event.keyCode;

			// 	// backspace

			// 	if ( keyCode == 8 ) {

			// 		event.preventDefault();

			// 		text = text.substring( 0, text.length - 1 );
			// 		refreshText();

			// 		return false;

			// 	}

			// }

			// function onDocumentKeyPress( event:Event ) {

			// 	const keyCode = event.which;

			// 	// backspace

			// 	if ( keyCode == 8 ) {

			// 		event.preventDefault();

			// 	} else {

			// 		const ch = String.fromCharCode( keyCode );
			// 		text += ch;

			// 		refreshText();

			// 	}

			// }

			